/*
 *  torsionfreebeam.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 01/08/2012
 *
 */

#include "torsionfreebeam.h"

TorsionFreeBeam::TorsionFreeBeam(ifstream &in, string cname, MecSystem *pSys, vector<string> & allPoints, vector<vector<string> >& triads, string matN, double totalL, double ar, double Isec)
:	Joint(in,cname,pSys),
	matName(matN),
	area(ar),
	isec(Isec),
	L(totalL)
{

	dim = parentSystem->dim;	/** Must be set always.  dim belongs to the mother class Joint */
	nelem = triads.size();
	nsegments = allPoints.size()-1;
		
	int i;
	vector<string> auxsv(2);

	for (i=0; i<nsegments; ++i)
	{
		auxsv[0] = allPoints[i];
		auxsv[1] = allPoints[i+1];
		vConstraints.push_back(new Consdis(auxsv,dim));
	}
	for (i=0; i<nelem; ++i)
	{
		vConstraints.push_back(new Align3P(triads[i],dim));
	}
}

// ***


void TorsionFreeBeam::setPTPointsCons()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vConstraints.size(); j++)		
		//Loop on the Loads
	{
		auxs = (vConstraints[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
			// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vConstraints[j]->setMPoints(maux);
		maux.clear();
	}		
}

// ***

void TorsionFreeBeam::setPPointSurface()
{}

// ***
/*
void TorsionFreeBeam::writeFileGraph(ofstream &fGraph, string& gFormat)
{}
*/
// ***

void TorsionFreeBeam::writeMSH(ofstream &fGraph)
{}

// ***

void TorsionFreeBeam::writeVTU(ofstream &fGraph)
{
	localFGraph << "<?xml version=\"1.0\"?>\n";
	localFGraph << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
	localFGraph << "	<UnstructuredGrid>\n";
	localFGraph << "		<Piece NumberOfPoints=\"" << 0 << "\" NumberOfCells=\"" << 0 << "\">\n";
	localFGraph << "			<Points>\n";
	localFGraph << "				<DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "			</Points>\n";
	localFGraph<< "			<Cells>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">";
	
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";

	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph<< "			</Cells>\n";
	
	localFGraph << "		</Piece>\n";
	
	localFGraph << "	</UnstructuredGrid>\n";
	localFGraph << "</VTKFile>\n";
}

// ***

void TorsionFreeBeam::writeOOGL(ofstream &fGraph)
{}

// ***

void TorsionFreeBeam::setParamAtCons()
{
      int i;
      Material* mat;
      vector<double> param(2);

      mat = parentSystem->getPTMaterial(matName);
      // Axial stiffness
      param[0] = (mat->getE())*area*nsegments/L;
      // Bending stiffness
      double coef = 48*(mat->getE())*isec/(L*L*L*L*L);
      if (nelem<=7)
      {
		param[1] = -45.8750;
		param[1] += 75.0417*nelem;
		param[1] -= 33.6250*nelem*nelem;
		param[1] += 5.4583*nelem*nelem*nelem;
      }
      else if (nelem>7)
      {
         param[1] = 0.062428;
         param[1] += 0.229187*nelem;
         param[1] += 0.333331*nelem*nelem;
         param[1] += 0.250000*nelem*nelem*nelem;
         param[1] += 0.104167*nelem*nelem*nelem*nelem;
         param[1] += 0.020833*nelem*nelem*nelem*nelem*nelem;
      }
/*
cout << "nelem = " << nelem << endl;
cout << "nsegments = " << nelem << endl;
cout << "L = " << L << endl;
cout << "coef = " << coef << endl;
cout << "param1 = " << param[1] << endl;
*/
      param[1] *= coef;

//        cout << "Coeficientes" << param[0] << " , " << param[1] << endl;
      for(i=0; i<vConstraints.size(); i++)
      {
		  vConstraints[i]->setParamAtCons(param);
      }
}
